package jp.eisbahn.mgapi.api.message;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import jp.eisbahn.mgapi.api.NopResponse;
import jp.eisbahn.mgapi.api.Request;
import jp.eisbahn.mgapi.api.Response;
import jp.eisbahn.mgapi.http.ContentType;
import jp.eisbahn.mgapi.http.HttpMethod;

/**
 * This request class is used when to access to Message API.
 * @author Yoichiro Tanaka
 */
public class MessageRequest implements Request {

    /** The user ID. */
    private String userId;
    /** The message ID. */
    private String messageId;
    /** The title. */
    private String title;
    /** The body. */
    private String body;
    /** The recipients. */
    private String[] recipients;
    /** The status. */
    private Status status;
    /** The request type. */
    private RequestType requestType;

    /** Base URI to get a message list. */
    private static final String GET_MESSAGE_LIST_BASE_URI =
        "/messages/{userId}/@inbox";
    /** Base URI to get a message. */
    private static final String GET_MESSAGE_BASE_URI =
        "/messages/{userId}/@inbox/{messageId}";
    /** Base URI to send a message. */
    private static final String SEND_MESSAGE_BASE_URI =
        "/messages/{userId}/@self/@outbox";
    /** Base URI to change a message status. */
    private static final String CHANGE_MESSAGE_STATUS_BASE_URI =
        "/messages/{userId}/@self/@inbox/{messageId}";
    /** Base URI to delete a message. */
    private static final String DELETE_MESSAGE_BASE_URI =
        "/messages/{userId}/@self/@inbox/{messageId}";

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getUri()
     */
    @Override
    public final String getUri() {
        if (requestType == RequestType.GET_MESSAGE_LIST) {
            return GET_MESSAGE_LIST_BASE_URI.replace("{userId}", userId);
        } else if (requestType == RequestType.GET_MESSAGE) {
                return GET_MESSAGE_BASE_URI
                    .replace("{userId}", userId)
                    .replace("{messageId}", messageId);
        } else if (requestType == RequestType.SEND_MESSAGE) {
                    return SEND_MESSAGE_BASE_URI.replace("{userId}", userId);
        } else if (requestType == RequestType.CHANGE_MESSAGE_STATUS) {
            return CHANGE_MESSAGE_STATUS_BASE_URI
                    .replace("{userId}", userId)
                    .replace("{messageId}", messageId);
        } else if (requestType == RequestType.DELETE_MESSAGE) {
            return DELETE_MESSAGE_BASE_URI
                    .replace("{userId}", userId)
                    .replace("{messageId}", messageId);
        } else {
            throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHttpMethod()
     */
    @Override
    public final HttpMethod getHttpMethod() {
        switch (requestType) {
            case GET_MESSAGE_LIST:
            case GET_MESSAGE:
                return HttpMethod.GET;
            case SEND_MESSAGE:
                return HttpMethod.POST;
            case CHANGE_MESSAGE_STATUS:
                return HttpMethod.PUT;
            case DELETE_MESSAGE:
                return HttpMethod.DELETE;
            default:
                throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getResponseClass()
     */
    @Override
    public final Class<? extends Response> getResponseClass() {
        switch (requestType) {
            case GET_MESSAGE_LIST:
            case GET_MESSAGE:
                return MessageResponse.class;
            case SEND_MESSAGE:
            case CHANGE_MESSAGE_STATUS:
            case DELETE_MESSAGE:
                return NopResponse.class;
            default:
                throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getContentType()
     */
    @Override
    public final ContentType getContentType() {
        return ContentType.JSON;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getParameterMap()
     */
    @Override
    public final Map<String, Object> getParameterMap() {
        Map<String, Object> result = new HashMap<String, Object>();
        if (requestType == RequestType.SEND_MESSAGE) {
            result.put("title", title);
            result.put("body", body);
            result.put("recipients", recipients);
        } else if (requestType == RequestType.CHANGE_MESSAGE_STATUS) {
            result.put("status", status.getReal());
        }
        return result;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getBodyStream()
     */
    @Override
    public final InputStream getBodyStream() {
        return null;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHeaderMap()
     */
    @Override
    public final Map<String, String> getHeaderMap() {
        return null;
    }

    /**
     * Set a userId value.
     * @param newUserId The userId to set
     */
    public final void setUserId(final String newUserId) {
        this.userId = newUserId;
    }

    /**
     * Retrieve the userId value.
     * @return The userId value.
     */
    public final String getUserId() {
        return userId;
    }

    /**
     * Set a messageId value.
     * @param newMessageId The messageId to set
     */
    public final void setMessageId(final String newMessageId) {
        this.messageId = newMessageId;
    }

    /**
     * Retrieve the messageId value.
     * @return The messageId value.
     */
    public final String getMessageId() {
        return messageId;
    }

    /**
     * Retrieve the title value.
     * @return The title value.
     */
    public final String getTitle() {
        return title;
    }

    /**
     * Set a title value.
     * @param newTitle The title to set
     */
    public final void setTitle(final String newTitle) {
        this.title = newTitle;
    }

    /**
     * Retrieve the body value.
     * @return The body value.
     */
    public final String getBody() {
        return body;
    }

    /**
     * Set a body value.
     * @param newBody The body to set
     */
    public final void setBody(final String newBody) {
        this.body = newBody;
    }

    /**
     * Retrieve the recipients value.
     * @return The recipients value.
     */
    public final String[] getRecipients() {
        return recipients;
    }

    /**
     * Set a recipients value.
     * @param newRecipients The recipients to set
     */
    public final void setRecipients(final String[] newRecipients) {
        this.recipients = newRecipients;
    }

    /**
     * Retrieve the status value.
     * @return The status value.
     */
    public final Status getStatus() {
        return status;
    }

    /**
     * Set a status value.
     * @param newStatus The status to set
     */
    public final void setStatus(final Status newStatus) {
        this.status = newStatus;
    }

    /**
     * Set a requestType value.
     * @param newRequestType The requestType to set
     */
    public final void setRequestType(final RequestType newRequestType) {
        this.requestType = newRequestType;
    }

    /**
     * Retrieve the requestType value.
     * @return The requestType value.
     */
    public final RequestType getRequestType() {
        return requestType;
    }

}
